mapasia: Add write support.
authoroliskoli <oliskoli>
Sat, 6 Sep 2008 22:27:04 +0000 (22:27 +0000)
committeroliskoli <oliskoli>
Sat, 6 Sep 2008 22:27:04 +0000 (22:27 +0000)
Makefile.in
mapasia.c

index 1e884f159f9b4c0d7cbad51e1429045a59d47d1d..26a798b322b99d2966b117d63228562a2fd5a0af 100644 (file)
@@ -757,7 +757,7 @@ tpo.o: tpo.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \
   jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h \
   jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h
 mapasia.o: mapasia.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \
-  zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h csv_util.h
+  zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h csv_util.h session.h
 trackfilter.o: trackfilter.c defs.h config.h queue.h gbtypes.h \
   zlib/zlib.h zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h \
   filterdefs.h strptime.h grtcirc.h
index e42d5fba6c72c4748807b615c63af3201b4c04ff..d85bdef22af0d51ad2dbae09e1de099f0a7bc98b 100644 (file)
--- a/mapasia.c
+++ b/mapasia.c
 #include <string.h>
 #include <time.h>
 #include "defs.h"
-#include "jeeps/gpsmath.h"
+#include "session.h"
 
-#define MYNAME "tr7"
+#define MYNAME "mapasia"
 
-#define TR7_TRACK_MAGIC        0x223eadb
+#define TR7_TRACK_MAGIC        0x223EADB
+
+#define TR7_S_SIZE     32
 
 #define TR7_S_YEAR     0
 #define TR7_S_MONTH    2
 #define TR7_S_VALID    28
 #define TR7_S_FIX      29
 
+static gbfile *fin, *fout;
+static const waypoint *wpt_tmp;
+static const route_head *trk_tmp;
+static int course_tmp, speed_tmp;
+
 static
 arglist_t tr7_args[] = {
        ARG_TERMINATOR
 };
 
-static gbfile *fin;
 
 /*******************************************************************************
 * %%%        global callbacks called by gpsbabel main process              %%% *
@@ -80,75 +86,188 @@ tr7_read(void)
        }
 
        while (! gbfeof(fin)) {
-               unsigned char buff[32];
+               unsigned char buff[TR7_S_SIZE];
+               double lat, lon;
+               struct tm tm;
+               waypoint *wpt;
+
                gbfread(buff, 1, sizeof(buff), fin);
-               if (buff[0] == 0xD8) {
-                       double lat, lon;
-                       struct tm tm;
-                       waypoint *wpt;
-
-                       memset(&tm, 0, sizeof(tm));
-
-                       lat = (double)le_read32(&buff[TR7_S_LAT]) / 1000000.0;
-                       lon = (double)le_read32(&buff[TR7_S_LON]) / 1000000.0;
-                       if ((fabs(lat) > 90) || (fabs(lon) > 180)) {
-                               trk = NULL;     
-                               continue;
-                       }
-
-                       tm.tm_year = le_read16(&buff[TR7_S_YEAR]) - 1900;
-                       tm.tm_mon = buff[TR7_S_MONTH] - 1;
-                       tm.tm_mday = buff[TR7_S_DAY];
-                       
-                       tm.tm_hour = buff[TR7_S_HOUR];
-                       tm.tm_min = buff[TR7_S_MIN];
-                       tm.tm_sec = buff[TR7_S_SEC];
-
-                       wpt = waypt_new();
-
-                       wpt->latitude = lat;
-                       wpt->longitude = lon;
+
+               memset(&tm, 0, sizeof(tm));
+
+               lat = (double)le_read32(&buff[TR7_S_LAT]) / 1000000.0;
+               lon = (double)le_read32(&buff[TR7_S_LON]) / 1000000.0;
+
+               if ((fabs(lat) > 90) || (fabs(lon) > 180)) {    /* that really happens */
+                       trk = NULL;     
+                       continue;
+               }
+
+               tm.tm_year = le_read16(&buff[TR7_S_YEAR]);
+               tm.tm_mon = buff[TR7_S_MONTH];
+               tm.tm_mday = buff[TR7_S_DAY];
+               tm.tm_hour = buff[TR7_S_HOUR];
+               tm.tm_min = buff[TR7_S_MIN];
+               tm.tm_sec = buff[TR7_S_SEC];
+
+               wpt = waypt_new();
+
+               wpt->latitude = lat;
+               wpt->longitude = lon;
+
+               /* create only valid timestamps */
+               if (tm.tm_mday && (tm.tm_mday <= 31) && tm.tm_mon && (tm.tm_mon <= 12) && (tm.tm_year > 1970)) {
+                       tm.tm_year -= 1900;
+                       tm.tm_mon -= 1;
                        wpt->creation_time = mkgmtime(&tm);
-                       WAYPT_SET(wpt, course, 360 - le_read16(&buff[TR7_S_COURSE]));
-                       WAYPT_SET(wpt, speed, (double)le_read16(&buff[TR7_S_SPEED]) / 3.6);
-#if 0
-                       /* unsure items */
-                       wpt->fix = buff[TR7_S_FIX];
-                       if (buff[TR7_S_VALID] != 'A') {
-                               waypt_free(wpt);
-                               continue;
-                       }
+               }
+
+               WAYPT_SET(wpt, course, 360 - le_read16(&buff[TR7_S_COURSE]));
+               WAYPT_SET(wpt, speed, KPH_TO_MPS(le_read16(&buff[TR7_S_SPEED])));
+
+#if 0          /* unsure, not validated items */
+               wpt->fix = buff[TR7_S_FIX];
+               if (buff[TR7_S_VALID] != 'A') {
+                       waypt_free(wpt);
+                       continue;
+               }
+#endif
+               if (waypt_speed(prev, wpt) > 9999.9) {  /* filter out some bad trackpoints */
+                       waypt_free(wpt);
+                       continue;
+               }
+
+               if (prev) {     /* other track or bad timestamp */
+                       if (wpt->creation_time && (prev->creation_time > wpt->creation_time)) trk = NULL;
+                       else if (waypt_distance(prev, wpt) > 9999.9) trk = NULL;
+               }
+
+               if (! trk) {
+                       trk = route_head_alloc();
+                       track_add_head(trk);
+               }
+               track_add_wpt(trk, wpt);
+               prev = wpt;
+       }
+}
+
+/**************************************************************************/
+
+static void
+tr7_disp_track_head_cb(const route_head *trk)
+{
+       wpt_tmp = NULL;
+}
+
+static void
+tr7_disp_waypt_cb(const waypoint *wpt)
+{
+       unsigned char buff[TR7_S_SIZE];
+       struct tm tm;
+       double speed, course;
+       
+       memset(buff, 0, sizeof(buff));
+       
+       le_write32(&buff[TR7_S_LON], (int)(wpt->longitude * 1000000.0));
+       le_write32(&buff[TR7_S_LAT], (int)(wpt->latitude * 1000000.0));
+
+       if WAYPT_HAS(wpt, course) course = wpt->course;
+       else if (wpt_tmp != NULL) course =  waypt_course(wpt_tmp, wpt);
+       else course = -1;
+       if (course >= 0) le_write16(&buff[TR7_S_COURSE], (int)(360 - course));
+
+       if (wpt->creation_time) {
+               tm = *gmtime(&wpt->creation_time);
+
+               le_write16(&buff[TR7_S_YEAR], tm.tm_year + 1900);
+               buff[TR7_S_MONTH] = tm.tm_mon + 1;
+               buff[TR7_S_DAY] = tm.tm_mday;
+               buff[TR7_S_HOUR] = tm.tm_hour;
+               buff[TR7_S_MIN] = tm.tm_min;
+               buff[TR7_S_SEC] = tm.tm_sec;
+
+               if WAYPT_HAS(wpt, speed) speed = wpt->speed;
+               else if (wpt_tmp != NULL) speed = waypt_speed(wpt_tmp, wpt);
+               else speed = -1;
+               if (speed >= 0) le_write16(&buff[TR7_S_SPEED], (int)MPS_TO_KPH(speed));
+       }
+       buff[TR7_S_VALID] = 'A';        /* meaning unknown */
+
+#if 0  /* not validated */
+       if (wpt->fix != fix_unknown) buff[TR7_S_FIX] = wpt->fix;
 #endif
-                       if (waypt_speed(prev, wpt) > 9999.9) {
-                               waypt_free(wpt);
-                               continue;
-                       }
-                       
-                       if (! trk) {
-                               trk = route_head_alloc();
-                               track_add_head(trk);
-                       }
-                       track_add_wpt(trk, wpt);
-                       prev = wpt;
+       gbfwrite(buff, 1, sizeof(buff), fout);
+       
+       wpt_tmp = wpt;
+}
+
+static void
+tr7_wr_init(const char *fname)
+{
+       fout = gbfopen_le(fname, "wb", MYNAME);
+       gbfputint32(TR7_TRACK_MAGIC, fout);
+}
+
+static void
+tr7_check_after_read_head_cb(const route_head *trk)
+{
+       trk_tmp = trk;
+       course_tmp = 0;
+       speed_tmp = 0;
+}
+
+static void
+tr7_check_after_read_wpt_cb(const waypoint *wpt)
+{
+       if (wpt->speed != 0) speed_tmp = 1;
+       if (wpt->course != 360.0) course_tmp = 1;       
+}
+
+static void
+tr7_check_after_read_trailer_cb(const route_head *trk)
+{
+       queue *elem, *tmp;
+       QUEUE_FOR_EACH((queue *)&trk->waypoint_list, elem, tmp) {
+               waypoint *wpt = (waypoint *)elem;
+               if (speed_tmp == 0) WAYPT_UNSET(wpt, speed);
+               if (course_tmp == 0) {
+                       WAYPT_UNSET(wpt, course);
+                       wpt->course = 0;
                }
        }
 }
 
+static void
+tr7_wr_deinit(void)
+{
+       track_disp_session(curr_session(), 
+               tr7_check_after_read_head_cb, 
+               tr7_check_after_read_trailer_cb,
+               tr7_check_after_read_wpt_cb);
+       gbfclose(fout);
+}
+
+static void
+tr7_write(void)
+{
+       track_disp_all(tr7_disp_track_head_cb, NULL, tr7_disp_waypt_cb);
+}
+
 /**************************************************************************/
 
-ff_vecs_t mapasia_tr7_vecs = {         /* currently we can only read tracks */
+ff_vecs_t mapasia_tr7_vecs = {         /* we can read and write tracks */
        ff_type_file,
        { 
-               ff_cap_none     /* waypoints */, 
-               ff_cap_read     /* tracks */, 
-               ff_cap_none     /* routes */
+               ff_cap_none                     /* waypoints */, 
+               ff_cap_read | ff_cap_write      /* tracks */, 
+               ff_cap_none                     /* routes */
        },
        tr7_rd_init,    
-       NULL,
+       tr7_wr_init,
        tr7_rd_deinit,  
-       NULL,
+       tr7_wr_deinit,
        tr7_read,
-       NULL,
+       tr7_write,
        NULL,
        tr7_args,
        CET_CHARSET_UTF8, 1     /* FIXED - CET-REVIEW - */